import 'dart:async';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:image_picker/image_picker.dart';

import '../../apis/base.dart';
import '../../config/global_config.dart';
import '../../utils/screenutil/fit.dart';

class UploadImgs extends StatefulWidget {
  final Function onUpLoadResult;
  final Function onSeeImgs;

  UploadImgs({Key key, this.onUpLoadResult, this.onSeeImgs}) : super(key: key);

  @override
  _UploadImgsState createState() => _UploadImgsState(
        onUpLoadResult: this.onUpLoadResult,
        onSeeImgs: this.onSeeImgs,
      );
}

class _UploadImgsState extends State<UploadImgs> {
  final Function onUpLoadResult;
  final Function onSeeImgs;

  _UploadImgsState({
    this.onUpLoadResult,
    this.onSeeImgs,
  });

  // 开启相机或相册
  ImagePicker picker = ImagePicker();

  // 图片转化器
  File image;

  // 用于当前渲染的图片列表（与exposeImgList长度保持同步）
  List<UploadMap> currentImgList = [];

  // 向外界暴露的图片列表（与currentImgList长度保持同步）
  List<String> exposeImgList = [];

  // 样式
  TextStyle titleStyle = TextStyle(
    fontSize: 28.f,
  );
  TextStyle subtitleStyle = TextStyle(
    fontSize: 20.f,
    color: GlobalConfig.assistColor,
  );

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Wrap(
        alignment: WrapAlignment.end,
        spacing: 0,
        runSpacing: 0,
        children: [
          Wrap(
            alignment: WrapAlignment.end,
            spacing: 0,
            runSpacing: 0,
            children: currentImgList.length > 0
                ? createImgGroups()
                : [SizedBox.shrink()],
          ),

          // 上传按钮
          Offstage(
            offstage: currentImgList.length >= 3,
            child: Container(
              width: 100.f,
              height: 100.f,
              margin: EdgeInsets.only(top: 10.f),
              decoration: BoxDecoration(
                border: Border.all(color: GlobalConfig.borderColor),
                borderRadius: BorderRadius.circular(10.f),
              ),
              child: FlatButton(
                color: Colors.white,
                splashColor: Colors.grey,
                child: Icon(
                  Icons.camera_alt,
                  color: GlobalConfig.assistColor,
                ),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10.f),
                ),
                onPressed: () => createModalBottomSheet(context),
              ),
            ),
          )
        ],
      ),
    );
  }

  // 创建图片组
  List<Widget> createImgGroups() {
    List<Widget> w = [];
    for (int i = 0; i < currentImgList.length; i++) {
      w.add(
        Stack(
          children: [
            Container(
              width: 120.f,
              height: 120.f,
            ),
            Positioned(
              top: 10.f,
              right: 10.f,
              child: InkWell(
                onTap: () => widget.onSeeImgs(i),
                child: Container(
                  width: 100.f,
                  height: 100.f,
                  decoration: BoxDecoration(
                    border:
                        Border.all(color: GlobalConfig.assistColor, width: 1.f),
                    borderRadius: BorderRadius.circular(5.f),
                  ),
                  //currentImgList[i].files,
                  child: Image.file(
                    currentImgList[i].files,
                    fit: BoxFit.cover,
                    width: 100.f,
                    height: 100.f,
                  ),
                ),
              ),
            ),
            currentImgList[i].status
                ? Positioned(
                    top: 0,
                    right: 0,
                    child: InkWell(
                      onTap: () => removeLF(i),
                      child: Container(
                        width: 30.f,
                        height: 30.f,
                        alignment: Alignment.center,
                        decoration: BoxDecoration(
                          color: Colors.black,
                          borderRadius: BorderRadius.circular(30.f),
                        ),
                        child: Icon(
                          Icons.clear,
                          size: 20.f,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  )
                : SizedBox.shrink(),
            currentImgList[i].status
                ? SizedBox.shrink()
                : Positioned(
                    top: 10.f,
                    left: 10.f,
                    child: Container(
                      width: 100.f,
                      height: 100.f,
                      color: Color.fromRGBO(51, 51, 51, .8),
                      child: SpinKitFadingCircle(
                        color: Color.fromRGBO(58, 98, 237, .9),
                        size: 50.f,
                      ),
                    ),
                  ),
          ],
        ),
      );
    }
    return w;
  }

  // 弹出底部模态窗
  // * [context] BuildContext|上下文|必填
  Future<void> createModalBottomSheet(BuildContext context) async {
    showModalBottomSheet(
      context: context,
      backgroundColor: Color.fromRGBO(0, 0, 0, 0),
      builder: (BuildContext context) {
        return ClipRRect(
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(20.f),
            topRight: Radius.circular(20.f),
          ),
          child: Container(
            color: Colors.white,
            height: 260.f,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                InkWell(
                  onTap: () {
                    getImage(ImageSource.camera);
                    Navigator.of(context).pop();
                  },
                  child: Container(
                    width: 640.f,
                    height: 120.f,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text("立即拍摄", style: titleStyle),
                        SizedBox(height: 10.f),
                        Text("未拍摄现场照片可点击此选项", style: subtitleStyle),
                      ],
                    ),
                  ),
                ),
                SizedBox(
                  height: 1.f,
                  child: Container(
                    color: GlobalConfig.borderColor,
                  ),
                ),
                InkWell(
                  onTap: () {
                    getImage(ImageSource.gallery);
                    Navigator.of(context).pop();
                  },
                  child: Container(
                    width: 640.f,
                    height: 120.f,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text("相册中选取", style: titleStyle),
                        SizedBox(height: 10.f),
                        Text("已拍摄现场照片可点击此选项", style: subtitleStyle),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  // 获取图片信息
  // * [type] ImageSource|获取图片的方式|必填
  // gallery：相册中选取|camera：相机拍摄
  Future getImage(ImageSource type) async {
    // 选取图片（含拍摄）
    final pickedFile = await picker.getImage(
      source: type,
      maxWidth: 750.f, // * 该属性对原图进行压缩
    );

    // 创建图片上传动画
    setState(() {
      currentImgList.insert(0, UploadMap(false, File(pickedFile.path)));
    });

    // 解析图片路径
    FormData f = await _analysis(pickedFile.path);

    // 上传文件
    try {
      String result = await Base.uploadfile(f);

      setState(() {
        currentImgList[0].status = true;
        // exposeImgList.insert(0, "${BaseConfig.BASEURL.IMG['m1']}${result}");
        exposeImgList.insert(0, "${result}");
        widget.onUpLoadResult(exposeImgList);
      });
    } catch (e) {
      // 移除上传的图片
      removeLF(0, isRemove: false);
    }
  }

  /// 参数解析（此处函数只针对向前组件使用）
  /// [str] String|图片路径|必填
  Future<FormData> _analysis(String str) async {
    // 拆解图片路径
    String name = str.substring(str.lastIndexOf("/") + 1, str.length),
        suffix = name.substring(name.lastIndexOf(".") + 1, name.length);

    // 文件中的`file`需与接口中的键名一致
    return FormData.fromMap({
      "file": await MultipartFile.fromFile(str, filename: name),
    });
  }

  /// 移除指定的图片
  /// * [i] int|图像下标|必填
  /// * [isRemove] bool|是否移除图片|选填
  void removeLF(int i, {bool isRemove = true}) {
    setState(() {
      currentImgList.removeAt(i);
      if (isRemove) exposeImgList.removeAt(i);
      widget.onUpLoadResult(exposeImgList);
    });
  }
}

class UploadMap {
  bool status;
  File files;

  UploadMap(status, files) {
    this.status = status;
    this.files = files;
  }
}
